home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / graphics / icontools / ficon11.lha / ForceIcon / Source / Support.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-04  |  28.5 KB  |  1,275 lines

  1. /*
  2. Auto:        smake ForceIcon
  3. */
  4.  
  5. /* $Revision Header built automatically *************** (do not edit) ************
  6. **
  7. ** © Copyright by GuntherSoft
  8. **
  9. ** File             : SnakeSYS:CPrgs/Utils/ForceIcon/Support.c
  10. ** Created on       : Friday, 22.10.93 16:38:41
  11. ** Created by       : Kai Iske
  12. ** Current revision : V1.0
  13. **
  14. **
  15. ** Purpose
  16. ** -------
  17. **   - Support-Routines for ForceIcon
  18. **
  19. ** Revision V1.0
  20. ** --------------
  21. ** created on Friday, 22.10.93 16:38:41  by  Kai Iske.   LogMessage :
  22. **     --- Initial release ---
  23. **
  24. *********************************************************************************/
  25.  
  26.  
  27.  
  28. /**********************************************************************/
  29. /*                         External variables                         */
  30. /**********************************************************************/
  31. extern struct    ExecBase    *SysBase;
  32. extern struct    SignalSemaphore    MySemaphore;
  33. extern struct    List        VolumeList;
  34. extern struct    IClass        *GetFileClass;
  35.  
  36.  
  37. /**********************************************************************/
  38. /*                          Global variables                          */
  39. /**********************************************************************/
  40. static struct    RastPort    ComputeRPort;
  41.  
  42.  
  43.  
  44. /**********************************************************************/
  45. /*                       Vars for Busy-Pointer                        */
  46. /**********************************************************************/
  47. static UWORD __chip BusyPtr[] =
  48. {
  49.     0x0000,0x0000,0x0400,0x07C0,0x0000,0x07C0,
  50.     0x0100,0x0380,0x0000,0x07E0,0x07C0,0x1FF8,
  51.     0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
  52.     0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,
  53.     0x3FF8,0x7FFE,0x3FF8,0x7FFE,0x1FF0,0x3FFC,
  54.     0x07C0,0x1FF8,0x0000,0x07E0,0x0000,0x0000
  55. };
  56.  
  57.  
  58.  
  59. /**********************************************************************/
  60. /*                          Calc X-Position                           */
  61. /**********************************************************************/
  62. UWORD ComputeX(UWORD value, UWORD FontX)
  63. {
  64.     return((UWORD)(((FontX * value) + 2) / 8));
  65. }
  66.  
  67.  
  68.  
  69.  
  70.  
  71. /**********************************************************************/
  72. /*                          Calc Y-Position                           */
  73. /**********************************************************************/
  74. UWORD ComputeY(UWORD value, UWORD FontY)
  75. {
  76.     return(( UWORD )((( FontY * value ) + 2 ) / 8 ));
  77. }
  78.  
  79.  
  80.  
  81.  
  82. /**********************************************************************/
  83. /*                  Calc resolution and correct font                  */
  84. /**********************************************************************/
  85. void __stdargs ComputeFont(struct Screen *WorkScreen, UWORD width, UWORD height, struct TextAttr *Font, char *FontName, UWORD *OffX, UWORD *OffY, UWORD *FontX, UWORD *FontY)
  86. {
  87.         // Get Font-Structure
  88.  
  89.     strcpy(FontName, WorkScreen->RastPort.Font->tf_Message.mn_Node.ln_Name);
  90.  
  91.     Font->ta_Name    = FontName;
  92.     Font->ta_YSize    = *FontY = WorkScreen->RastPort.Font->tf_YSize;
  93.     Font->ta_Style    = FS_NORMAL;
  94.     Font->ta_Flags    = 0;
  95.  
  96.     *FontX        = WorkScreen->RastPort.Font->tf_XSize;
  97.  
  98.  
  99.         // Calc offsets
  100.  
  101.     *OffX = WorkScreen->WBorLeft;
  102.     *OffY = WorkScreen->RastPort.TxHeight + WorkScreen->WBorTop + 1;
  103.  
  104.  
  105.         // A Ok ???
  106.  
  107.     if(width && height)
  108.     {
  109.         if((ComputeX(width, *FontX) + *OffX + WorkScreen->WBorRight) > WorkScreen->Width)
  110.             goto UseTopaz;
  111.         if((ComputeY(height, *FontY) + *OffY + WorkScreen->WBorBottom) > WorkScreen->Height)
  112.             goto UseTopaz;
  113.     }
  114.     return;
  115.  
  116.         // FallBack to Topaz8
  117. UseTopaz:
  118.     strcpy(FontName, "topaz.font");
  119.     *FontX = *FontY = Font->ta_YSize = 8;
  120. }
  121.  
  122.  
  123.  
  124.  
  125. /**********************************************************************/
  126. /*              Open a window with a background pattern               */
  127. /**********************************************************************/
  128. BOOL OpenWin(
  129.             UWORD    Left,
  130.             UWORD    Top,
  131.             UWORD    Width,
  132.             UWORD    Height,
  133.             struct    Gadget        **BaseGadget,
  134.             UWORD    NumGads,
  135.             struct    _Object        **GetFile,
  136.             struct    NewGadget    *NewGads,
  137.             UWORD    *GTypes,
  138.             ULONG    *GTags,
  139.             struct    Gadget        **MyGads,
  140.             struct    Window        **Handle,
  141.             char    *Title,
  142.             ULONG    IDCMP,
  143.             ULONG    FLAGS,
  144.             UWORD    MLeft,
  145.             UWORD    MTop,
  146.             UWORD    MWidth,
  147.             UWORD    MHeight,
  148.             struct    TextAttr    *WinTxtAttr,
  149.             char            *WinTxtFontName,
  150.             struct    VisualInfo    **VisInfo)
  151. {
  152.     UWORD Raster[4] =
  153.     {
  154.         0xAAAA,
  155.         0x5555,
  156.     };
  157.     struct    Screen        *MyScreen;
  158.     struct    Rectangle    ScrRec;
  159.     struct    NewGadget    ng;
  160.     struct    Gadget        *g;
  161.     struct    TextFont    *MyFont = NULL;
  162.     UWORD    lc, tc;
  163.     UWORD    wleft, wtop, ww, wh, OffX, OffY, FontX, FontY,
  164.         swidth, sheight;
  165.  
  166.  
  167.     if(!(MyScreen = LockPubScreen("Workbench")))
  168.         return(FALSE);
  169.  
  170.     if(!(*VisInfo = GetVisualInfo(MyScreen, TAG_DONE)))
  171.         goto error;
  172.  
  173.         // Get Font and dimensions
  174.  
  175.     ComputeFont(MyScreen, Width, Height, WinTxtAttr, WinTxtFontName, &OffX, &OffY, &FontX, &FontY);
  176.  
  177.  
  178.         // Set RastPort Font
  179.  
  180.     InitRastPort(&ComputeRPort);
  181.     if(!(MyFont = OpenFont(WinTxtAttr)))
  182.     {
  183.         if(!(MyFont = OpenDiskFont(WinTxtAttr)))
  184.             goto error;
  185.     }
  186.     SetFont(&ComputeRPort, MyFont);
  187.  
  188.  
  189.         // Get size of window
  190.  
  191.     ww = ComputeX(Width, FontX);
  192.     wh = ComputeY(Height, FontY);
  193.  
  194.  
  195.         // Get info about Screenmode
  196.  
  197.     if(!QueryOverscan(GetVPModeID(&MyScreen->ViewPort), &ScrRec, OSCAN_TEXT))
  198.         goto error;
  199.  
  200.         // Center window
  201.  
  202.     swidth    = min((ScrRec.MaxX + 1), MyScreen->Width);
  203.     sheight    = min((ScrRec.MaxY + 1), MyScreen->Height);
  204.  
  205.     wleft    = ((swidth - ww - 1) >> 1) - ((MyScreen->LeftEdge < 0) ? MyScreen->LeftEdge : 0);
  206.     wtop    = ((sheight - wh - 1) >> 1) - ((MyScreen->TopEdge < 0) ? MyScreen->TopEdge : 0);
  207.  
  208.  
  209.         // Build GetFile image
  210.  
  211.     if(GetFile)
  212.     {
  213.         if(!(*GetFile = NewObject(GetFileClass, NULL, GT_VisualInfo, *VisInfo, IA_Width, ComputeX(20, FontX), IA_Height, ComputeY(14, FontY), TAG_DONE)))
  214.             goto error;
  215.     }
  216.  
  217.         // Create gadgets
  218.  
  219.     if(!(g = CreateContext(BaseGadget)))
  220.         goto error;
  221.  
  222.     for(lc = 0, tc = 0; lc < NumGads; lc++)
  223.     {
  224.         CopyMem((char *)&NewGads[lc], (char *)&ng, (long)sizeof(struct NewGadget));
  225.  
  226.         ng.ng_VisualInfo    = *VisInfo;
  227.         ng.ng_TextAttr        = WinTxtAttr;
  228.         ng.ng_LeftEdge        = OffX + ComputeX(ng.ng_LeftEdge, FontX);
  229.         ng.ng_TopEdge        = OffY + ComputeY(ng.ng_TopEdge, FontY);
  230.         ng.ng_Width        = ComputeX(ng.ng_Width, FontX);
  231.         ng.ng_Height        = ComputeY(ng.ng_Height, FontY);
  232.  
  233.             // Set gadget`s shortcut
  234.  
  235.         SetGadShortCut(GTypes[lc], &ng);
  236.  
  237.             // Check for ListView
  238.  
  239.         if(GTypes[lc] == LISTVIEW_KIND)
  240.         {
  241.             struct TagItem    *tmp;
  242.  
  243.             if(tmp = FindTagItem(GTLV_ShowSelected, (struct TagItem *)>ags[tc]))
  244.             {
  245.                 if(tmp->ti_Data)
  246.                     tmp->ti_Data = (ULONG)g;
  247.                 else
  248.                 {
  249.                         // With a normal ShowSelected,
  250.                         // adjust width according to version of OS
  251.  
  252.                     if(((struct Library *)SysBase)->lib_Version < 39)
  253.                         ng.ng_Height    -= 8;
  254.                 }
  255.             }
  256.         }
  257.  
  258.             // Create gadget
  259.  
  260.         MyGads[lc] = g = CreateGadgetA(GTypes[lc], g, &ng, (struct TagItem *)>ags[tc]);
  261.  
  262.             // Error ???
  263.  
  264.         if(!g)
  265.             goto error;
  266.  
  267.             // Set GetFile image
  268.  
  269.         if(GTypes[lc] == GENERIC_KIND && GetFile)
  270.         {
  271.             struct    TagItem    *tmp;
  272.             BOOL    Disabled = FALSE;
  273.  
  274.             if((tmp = FindTagItem(GA_Disabled, (struct TagItem *)>ags[tc])))
  275.                 Disabled = (BOOL)tmp->ti_Data;
  276.  
  277.             g->Flags        |= GFLG_GADGIMAGE | GFLG_GADGHIMAGE | ((Disabled) ? GFLG_DISABLED : 0);
  278.             g->Activation        |= GACT_RELVERIFY;
  279.             g->GadgetType        |= GTYP_BOOLGADGET;
  280.             g->GadgetRender        = (APTR)*GetFile;
  281.             g->SelectRender        = (APTR)*GetFile;
  282.         }
  283.  
  284.             // Patch String/Integer Gadgets
  285.  
  286.         if(GTypes[lc] == STRING_KIND || GTypes[lc] == INTEGER_KIND)
  287.         {
  288.             ((struct StringInfo *)g->SpecialInfo)->Extension->ActivePens[0] = 1;
  289.             ((struct StringInfo *)g->SpecialInfo)->Extension->ActivePens[1] = 2;
  290.         }
  291.  
  292.         while(GTags[tc])
  293.             tc += 2;
  294.         tc++;
  295.     }
  296.  
  297.         // Close Font
  298.  
  299.     CloseFont(MyFont);
  300.  
  301.         // Open window
  302.  
  303.     if(!(*Handle = OpenWindowTags(NULL,
  304.         WA_Left,        wleft,
  305.         WA_Top,            wtop,
  306.         WA_Width,        ww + OffX + MyScreen->WBorRight,
  307.         WA_Height,        wh + OffY + MyScreen->WBorBottom,
  308.         WA_IDCMP,        IDCMP,
  309.         WA_Flags,        FLAGS,
  310.         WA_Title,        Title,
  311.         WA_CustomScreen,    MyScreen,
  312.     TAG_DONE)))
  313.         goto error;
  314.  
  315.         // Clear userdata-field
  316.  
  317.     (*Handle)->UserData    = NULL;
  318.  
  319.         // Unlock Pub screen
  320.  
  321.     UnlockPubScreen(NULL, MyScreen);
  322.  
  323.     if(MLeft && MTop && MWidth && MHeight)
  324.     {
  325.             // Draw Raster
  326.  
  327.         SetAPen((*Handle)->RPort, 2);
  328.         SetAfPt((*Handle)->RPort, Raster, 1);
  329.         RectFill((*Handle)->RPort, (*Handle)->BorderLeft, (*Handle)->BorderTop, (*Handle)->Width - (*Handle)->BorderRight - 1, (*Handle)->Height - (*Handle)->BorderBottom - 1);
  330.         SetAfPt((*Handle)->RPort, NULL, 0);
  331.  
  332.             // Clear gadget areas and draw bevelbox
  333.  
  334.         SetAPen((*Handle)->RPort, 0);
  335.  
  336.         wleft    = OffX + ComputeX(MLeft, FontX);
  337.         wtop    = OffY + ComputeY(MTop, FontY);
  338.         RectFill((*Handle)->RPort, wleft, wtop, wleft + ComputeX(MWidth, FontX) - 1, wtop + ComputeY(MHeight, FontY) - 1);
  339.         DrawBevelBox((*Handle)->RPort, wleft, wtop,
  340.             ComputeX(MWidth, FontX),
  341.             ComputeY(MHeight, FontY),
  342.             GT_VisualInfo, *VisInfo, GTBB_Recessed, TRUE,
  343.         TAG_DONE);
  344.     }
  345.  
  346.         // Add gadgets and display them
  347.  
  348.     AddGList((*Handle), *BaseGadget, -1, -1, NULL);
  349.     RefreshGadgets(*BaseGadget, (*Handle), NULL);
  350.  
  351.     GT_RefreshWindow((*Handle), NULL );
  352.     return(TRUE);
  353.  
  354. error:
  355.     if(MyScreen)
  356.         UnlockPubScreen(NULL, MyScreen);
  357.     if(MyFont)
  358.         CloseFont(MyFont);
  359.     return(FALSE);
  360.  
  361. }
  362.  
  363.  
  364.  
  365.  
  366.  
  367. /**********************************************************************/
  368. /*                        Close a window again                        */
  369. /**********************************************************************/
  370. void CloseWin(struct Window **Handle, struct Gadget **MyGad, struct VisualInfo **VisInfo, struct _Object **GetFile)
  371. {
  372.     if(*Handle)
  373.     {
  374.         CloseWindow((*Handle));
  375.         *Handle = NULL;
  376.     }
  377.  
  378.     if(*MyGad)
  379.     {
  380.         FreeGadgets((*MyGad));
  381.         *MyGad = NULL;
  382.     }
  383.  
  384.     if(*VisInfo)
  385.     {
  386.         FreeVisualInfo(*VisInfo);
  387.         *VisInfo = NULL;
  388.     }
  389.  
  390.     if(GetFile && *GetFile)
  391.     {
  392.         DisposeObject(*GetFile);
  393.         *GetFile = NULL;
  394.     }
  395. }
  396.  
  397.  
  398.  
  399.  
  400.  
  401. /**********************************************************************/
  402. /*                      Set a gadget`s shortcut                       */
  403. /**********************************************************************/
  404. void SetGadShortCut(UWORD Type, struct NewGadget *NewGad)
  405. {
  406.     char *UnderScore, MyChar;
  407.     ULONG EventType = 0;
  408.  
  409.         // Get char of ShortCut
  410.  
  411.     if(NewGad->ng_GadgetText && (UnderScore = (char *)strchr(NewGad->ng_GadgetText, '_')))
  412.     {
  413.         MyChar = *(UnderScore + 1);
  414.         NewGad->ng_UserData = (void *)ToUpper(MyChar);
  415.     }
  416.  
  417.         // Set type of event suited for Keystroke activation
  418.  
  419.     switch(Type)
  420.     {
  421.         case BUTTON_KIND :
  422.         case CYCLE_KIND :
  423.         case LISTVIEW_KIND :
  424.         case CHECKBOX_KIND :
  425.         {
  426.             EventType = IDCMP_GADGETUP;
  427.             break;
  428.         }
  429.         case STRING_KIND :
  430.         case INTEGER_KIND :
  431.         {
  432.             EventType = IDCMP_GADGETDOWN;
  433.             break;
  434.         }
  435.     }
  436.  
  437.     if(EventType)
  438.         NewGad->ng_UserData = (void *)((ULONG)NewGad->ng_UserData | (EventType << 8));
  439. }
  440.  
  441.  
  442.  
  443.  
  444.  
  445. /**********************************************************************/
  446. /*                    Get device and volume lists                     */
  447. /**********************************************************************/
  448. BOOL GetDevVolList(struct List *VolList)
  449. {
  450.     NewList(VolList);
  451.     VolList->lh_Type = 0;
  452.  
  453.     if(GetDosEntries(VolList, LDF_DEVICES))
  454.     {
  455.         if(GetDosEntries(VolList, LDF_VOLUMES))
  456.         {
  457.             SortList(VolList, FALSE);
  458.             return(TRUE);
  459.         }
  460.     }
  461.  
  462.     return(FALSE);
  463. }
  464.  
  465.  
  466.  
  467. /**********************************************************************/
  468. /*                     Collect available volumes                      */
  469. /**********************************************************************/
  470. BOOL GetDosEntries(struct List *VolList, ULONG Mode)
  471. {
  472.     struct    DosList        *DList;
  473.     struct    VolEntry    *NewEntry;
  474.     BOOL    RetVal        = FALSE;
  475.  
  476.         // Lock DOS-List of Volumes
  477.  
  478.     if((DList = LockDosList(Mode|LDF_READ)))
  479.     {
  480.             // Loop for all entries
  481.  
  482.         while(DList)
  483.         {
  484.                 // Get next entry
  485.  
  486.             if(!(DList = NextDosEntry(DList, Mode|LDF_READ)))
  487.                 RetVal = TRUE;
  488.             else
  489.             {
  490.                 BOOL    DoGet = TRUE;
  491.  
  492.                 if(DList->dol_Type == DLT_DEVICE)
  493.                 {
  494.                     struct    FileSysStartupMsg *FSSM = (struct FileSysStartupMsg *)BADDR(DList->dol_misc.dol_handler.dol_Startup);
  495.                     DoGet = FALSE;
  496.  
  497.                     if(FSSM && TypeOfMem(FSSM) && TypeOfMem(BADDR(FSSM->fssm_Device)) && TypeOfMem(BADDR(FSSM->fssm_Environ)))
  498.                     {
  499.                         if(*((char *)BADDR(FSSM->fssm_Device)) != 255)
  500.                         {
  501.                             struct    DosEnvec    *DE = (struct DosEnvec *)BADDR(FSSM->fssm_Environ);
  502.  
  503.                             if(DE && TypeOfMem(DE))
  504.                             {
  505.                                 if(DE->de_Surfaces && DE->de_BlocksPerTrack)
  506.                                     DoGet = TRUE;
  507.                             }
  508.                         }
  509.                     }
  510.                 }
  511.  
  512.                 if(DoGet)
  513.                 {
  514.                         // Alloc memory for new entry
  515.  
  516.                     if((NewEntry = AllocVec(sizeof(struct VolEntry), MEMF_CLEAR)))
  517.                     {
  518.                             // Add to list
  519.  
  520.                         AddTail(VolList, (struct Node *)NewEntry);
  521.                         NewEntry->Link.ln_Name    = NewEntry->VolName;
  522.                         NewEntry->Link.ln_Type    = Mode;
  523.                         VolList->lh_Type++;
  524.  
  525.                         strcpy(NewEntry->VolName, ((char *)BADDR(DList->dol_Name) + 1));
  526.                     }
  527.                     else
  528.                         DList = NULL;
  529.                 }
  530.             }
  531.         }
  532.  
  533.             // Unlock DOS-List again
  534.  
  535.         UnLockDosList(Mode|LDF_READ);
  536.     }
  537.  
  538.     if(!RetVal)
  539.         DisplayError(ERR_NOTALL, NULL);
  540.  
  541.     return(RetVal);
  542. }
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550. /**********************************************************************/
  551. /*                        Release Volume-Nodes                        */
  552. /**********************************************************************/
  553. void FreeDevVolList(struct List *VolList)
  554. {
  555.     struct    Node    *DelNode;
  556.  
  557.     while((DelNode = RemHead(VolList)))
  558.         FreeVec(DelNode);
  559. }
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566. /**********************************************************************/
  567. /*                     Check for gadget shortcuts                     */
  568. /**********************************************************************/
  569. void CheckKeys(ULONG *MsgClass, UWORD *MsgCode, UWORD *GadID, BOOL *KeyUse, struct Gadget **MsgGad, struct Gadget **EditGads, UWORD NumGads)
  570. {
  571.     register int i;
  572.  
  573.         // Key pressed ???
  574.  
  575.     if(*MsgClass == IDCMP_VANILLAKEY)
  576.     {
  577.             // Key released ???
  578.  
  579.         if(!(*MsgCode & IECODE_UP_PREFIX))
  580.         {
  581.                 // ESC hit ??? -> Return CLOSE WINDOW
  582.  
  583.             if(*MsgCode == ESCKEY)
  584.                 *MsgClass    = IDCMP_CLOSEWINDOW;
  585.  
  586.                 // On Return, search for the first String/Integer gadget
  587.  
  588.             else if(*MsgCode == 0x0d)
  589.             {
  590.                     // Search for gadget
  591.  
  592.                 for(i = 0; i < NumGads; i++)
  593.                 {
  594.                         // This is the one
  595.  
  596.                     if((EditGads[i]->GadgetType & GTYP_STRGADGET) && !(EditGads[i]->Flags & GFLG_DISABLED))
  597.                     {
  598.                             // Set flags and vars
  599.  
  600.                         *MsgGad        = EditGads[i];
  601.                         *MsgClass    = IDCMP_ACTSTRGAD;
  602.                         *KeyUse        = TRUE;
  603.                         break;
  604.                     }
  605.                 }
  606.             }
  607.             else
  608.             {
  609.                     // Get Char hit
  610.  
  611.                 *MsgCode = (UWORD)ToUpper((char)*MsgCode);
  612.  
  613.                     // Search for suited gadget
  614.  
  615.                 for(i = 0; i < NumGads; i++)
  616.                 {
  617.                     if(((ULONG)EditGads[i]->UserData & 0x000000ff) == (ULONG)*MsgCode)
  618.                     {
  619.                             // Set flags
  620.  
  621.                         *MsgGad        = EditGads[i];
  622.                         *GadID        = (*MsgGad)->GadgetID;
  623.                         *MsgClass    = ((ULONG)(*MsgGad)->UserData & 0x0000ff00) >> 8;
  624.                         *KeyUse        = TRUE;
  625.                         break;
  626.                     }
  627.                 }
  628.             }
  629.         }
  630.     }
  631.     else
  632.         *KeyUse = FALSE;
  633. }
  634.  
  635.  
  636.  
  637.  
  638.  
  639. /**********************************************************************/
  640. /*                      Handle a listview gadget                      */
  641. /**********************************************************************/
  642. ULONG HandleListViewGad(struct Gadget *Gad, struct Window *MsgWin, BOOL KeyUse, UWORD MsgCode, UWORD MsgQual, LONG Val, ULONG Min, ULONG Max)
  643. {
  644.     if(KeyUse)
  645.     {
  646.             // Key hit
  647.  
  648.         if(MsgQual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  649.         {
  650.                 // On SHIFT move up
  651.  
  652.             if((Val != Min) && (Val != -1))
  653.                 Val--;
  654.         }
  655.         else
  656.         {
  657.                 // On NON-SHIFT move down
  658.  
  659.             if(Val != Max)
  660.                 Val++;
  661.         }
  662.  
  663.             // Set gadget
  664.  
  665.         if(Val != -1)
  666.         {
  667.             GT_SetGadgetAttrs(Gad, MsgWin, NULL,
  668.                 GTLV_Selected,    Val,
  669.                 GTLV_Top,    Val,
  670.             TAG_DONE);
  671.         }
  672.     }
  673.     else
  674.             // Otherwiese simply get Message-Code
  675.  
  676.         Val = MsgCode;
  677.  
  678.  
  679.     return((ULONG)Val);
  680. }
  681.  
  682.  
  683.  
  684.  
  685. /**********************************************************************/
  686. /*                       Handle a cycle gadget                        */
  687. /**********************************************************************/
  688. ULONG HandleCycleGad(struct Gadget *Gad, struct Window *MsgWin, BOOL KeyUse, UWORD MsgCode, UWORD MsgQual, ULONG Val, ULONG Min, ULONG Max)
  689. {
  690.     if(KeyUse)
  691.     {
  692.             // Key hit
  693.  
  694.         if(MsgQual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  695.         {
  696.                 // On SHIFT move upward, on minimum jump to highest entry
  697.  
  698.             if(Val == Min)
  699.                 Val = Max;
  700.             else
  701.                 Val--;
  702.         }
  703.         else
  704.         {
  705.                 // On NON-SHIFT move downward, on maximum jump to lowest entry
  706.  
  707.             if(Val == Max)
  708.                 Val = Min;
  709.             else
  710.                 Val++;
  711.         }
  712.  
  713.             // Set gadget
  714.  
  715.         GT_SetGadgetAttrs(Gad, MsgWin, NULL,
  716.             GTCY_Active, Val,
  717.         TAG_DONE);
  718.     }
  719.     else
  720.             // Otherwise simply get MsgCode
  721.  
  722.         Val = MsgCode;
  723.  
  724.  
  725.     return(Val);
  726. }
  727.  
  728.  
  729.  
  730.  
  731. /**********************************************************************/
  732. /*                      Get an entry from a list                      */
  733. /**********************************************************************/
  734. APTR GetListEntry(struct List *List, WORD EntryNum)
  735. {
  736.     struct    Node    *ThisEntry = NULL, *CheckEntry;
  737.  
  738.         // Search list for entry
  739.  
  740.     if(!IsListEmpty((struct List *)List) && EntryNum >= 0)
  741.     {
  742.         CheckEntry = List->lh_Head;
  743.  
  744.         while(CheckEntry->ln_Succ && EntryNum)
  745.         {
  746.             CheckEntry    = CheckEntry->ln_Succ;
  747.             EntryNum--;
  748.         }
  749.  
  750.         if(!EntryNum)
  751.             ThisEntry    = CheckEntry;
  752.     }
  753.  
  754.     return(ThisEntry);
  755. }
  756.  
  757.  
  758.  
  759.  
  760. /**********************************************************************/
  761. /*                        Set a window to Busy                        */
  762. /**********************************************************************/
  763. void BusyWindow(struct Window *Window, struct Requester *MyReq)
  764. {
  765.     if(Window)
  766.     {
  767.             // Clear Requester structure
  768.  
  769.         setmem((void *)MyReq, sizeof(struct Requester), 0);
  770.  
  771.             // Open Requester and store address within UserData
  772.  
  773.         Window->UserData = (char *)Request(MyReq, Window);
  774.  
  775.             // Set Pointer
  776.  
  777.         if(SysBase->LibNode.lib_Version < 39)
  778.             SetPointer(Window, &BusyPtr[0],  16, 16, -6, 0);
  779.         else
  780.             SetWindowPointer(Window, WA_BusyPointer, TRUE, TAG_DONE);
  781.     }
  782. }
  783.  
  784.  
  785.  
  786.  
  787. /**********************************************************************/
  788. /*                          UnBusy a window                           */
  789. /**********************************************************************/
  790. void UnBusyWindow(struct Window *Window, struct Requester *MyReq)
  791. {
  792.     if(Window)
  793.     {
  794.             // Close Requester
  795.  
  796.         if(Window->UserData)
  797.             EndRequest(MyReq, Window);
  798.         Window->UserData = NULL;
  799.  
  800.             // Reset Pointer
  801.  
  802.         if(SysBase->LibNode.lib_Version < 39)
  803.             ClearPointer(Window);
  804.         else
  805.             SetWindowPointer(Window, TAG_DONE);
  806.     }
  807. }
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815. /**********************************************************************/
  816. /*                       Save Prefs to disk/env                       */
  817. /**********************************************************************/
  818. BOOL SavePrefs(BOOL EnvMode)
  819. {
  820.         // On ENV: mode, simply save to ENV: only
  821.  
  822.     if(DoSavePrefs("ENV:ForceIcon_prefs.iff"))
  823.     {
  824.             // Otherwise write to envarc: as well
  825.  
  826.         if(!EnvMode)
  827.             return(DoSavePrefs("ENVARC:ForceIcon_prefs.iff"));
  828.         else
  829.             return(TRUE);
  830.     }
  831.     return(FALSE);
  832. }
  833. BOOL DoSavePrefs(char *PrefsName)
  834. {
  835.     struct    IFFHandle    *PrefsHandle;
  836.     LONG    Error;
  837.     BOOL    GoOn = FALSE;
  838.     UWORD    VersChunk[] =
  839.     {
  840.         VERNUM,
  841.         REVNUM
  842.     };
  843.  
  844.         // Get handle for IFF
  845.  
  846.     if((PrefsHandle = AllocIFF()))
  847.     {
  848.             // Open file for save
  849.  
  850.         if((PrefsHandle->iff_Stream = Open(PrefsName, MODE_NEWFILE)))
  851.         {
  852.                 // Init Handle
  853.  
  854.             InitIFFasDOS(PrefsHandle);
  855.  
  856.                 // Open Handle
  857.  
  858.             if(!(Error = OpenIFF(PrefsHandle, IFFF_WRITE)))
  859.             {
  860.                     // Write FORM chunk
  861.  
  862.                 if(!(Error = PushChunk(PrefsHandle, 'FOIC', 'FORM', IFFSIZE_UNKNOWN)))
  863.                 {
  864.                         // Write version chunk
  865.  
  866.                     if(!(Error = PushChunk(PrefsHandle, 'FOIC', 'VERS', IFFSIZE_UNKNOWN)))
  867.                     {
  868.                         if((Error = WriteChunkBytes(PrefsHandle, &VersChunk[0], (sizeof(UWORD) * 2))) == (sizeof(UWORD) * 2))
  869.                             Error = PopChunk(PrefsHandle);
  870.                         else
  871.                             Error = IoErr();
  872.                     }
  873.  
  874.                         // Write Prefs chunk
  875.  
  876.                     if(!Error && !(Error = PushChunk(PrefsHandle, 'FOIC', 'PREF', IFFSIZE_UNKNOWN)))
  877.                     {
  878.                         struct    VolEntry    *ThisEntry    = (struct VolEntry *)VolumeList.lh_Head;
  879.                         UWORD    NumEntries            = VolumeList.lh_Type;
  880.                         BOOL    NoErr = TRUE;
  881.  
  882.                                 // Write all entries of volume list
  883.  
  884.                         if((Error = WriteChunkBytes(PrefsHandle, &NumEntries, sizeof(UWORD))) == sizeof(UWORD))
  885.                         {
  886.                             while(NumEntries-- && NoErr)
  887.                             {
  888.                                 UWORD    EntryType = ThisEntry->Link.ln_Type;
  889.  
  890.                                 if((Error = WriteChunkBytes(PrefsHandle, &EntryType, sizeof(UWORD))) == sizeof(UWORD))
  891.                                 {
  892.                                     if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->VolName, 130)) == 130)
  893.                                     {
  894.                                         if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->IconName, 256)) == 256)
  895.                                         {
  896.                                             if((Error = WriteChunkBytes(PrefsHandle, &ThisEntry->Left, (sizeof(UWORD) * 4))) != (sizeof(UWORD) * 4))
  897.                                                 NoErr = FALSE;
  898.                                         }
  899.                                     }
  900.                                 }
  901.  
  902.                                 ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  903.                             }
  904.  
  905.                             if(NoErr)
  906.                             {
  907.                                 if(!(Error = PopChunk(PrefsHandle)))
  908.                                     GoOn = TRUE;
  909.                             }
  910.                         }
  911.                     }
  912.                 }
  913.  
  914.                 if((Error = PopChunk(PrefsHandle)))
  915.                     GoOn = FALSE;
  916.  
  917.                 CloseIFF(PrefsHandle);
  918.             }
  919.  
  920.             Close(PrefsHandle->iff_Stream);
  921.         }
  922.         else
  923.             Error = IoErr();
  924.  
  925.         FreeIFF(PrefsHandle);
  926.     }
  927.     else
  928.         Error = ERR_NOMEM;
  929.  
  930.     if(!GoOn)
  931.         DisplayError(Error, (ULONG)PrefsName, NULL);
  932.  
  933.     return(GoOn);
  934. }
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942. /**********************************************************************/
  943. /*                          Load in settings                          */
  944. /**********************************************************************/
  945. void LoadPrefs(void)
  946. {
  947.         // Try env: first, then envarc:
  948.     if(!DoLoadPrefs("ENV:ForceIcon_prefs.iff"))
  949.         DoLoadPrefs("ENVARC:ForceIcon_prefs.iff");
  950. }
  951. BOOL DoLoadPrefs(char *PrefsName)
  952. {
  953.     struct    IFFHandle    *PrefsHandle;
  954.     struct    StoredProperty    *SP;
  955.     UWORD    *VersCheck;
  956.     LONG    Error;
  957.     BOOL    GoOn = FALSE;
  958.  
  959.         // Initialize Lists first
  960.  
  961.     NewList(&VolumeList);
  962.     VolumeList.lh_Type = 0;
  963.  
  964.         // Get Prefs Handle
  965.  
  966.     if((PrefsHandle = AllocIFF()))
  967.     {
  968.             // Open file
  969.  
  970.         if((PrefsHandle->iff_Stream = Open(PrefsName, MODE_OLDFILE)))
  971.         {
  972.                 // Init handle
  973.  
  974.             InitIFFasDOS(PrefsHandle);
  975.  
  976.                 // Open Handle
  977.  
  978.             if(!(Error = OpenIFF(PrefsHandle, IFFF_READ)))
  979.             {
  980.                     // Search for version chunk
  981.  
  982.                 if(!(Error = PropChunk(PrefsHandle, 'FOIC', 'VERS')))
  983.                 {
  984.                         // Stop at prefs
  985.  
  986.                     if(!(Error = StopChunk(PrefsHandle, 'FOIC', 'PREF')))
  987.                     {
  988.                             // Start parsing
  989.  
  990.                         if(!(Error = ParseIFF(PrefsHandle, IFFPARSE_SCAN)))
  991.                         {
  992.                                 // Try to find version chunk
  993.  
  994.                             if((SP = FindProp(PrefsHandle, 'FOIC', 'VERS')))
  995.                             {
  996.                                 VersCheck = (UWORD *)SP->sp_Data;
  997.  
  998.                                     // Check Version number
  999.  
  1000.                                 if(((*VersCheck) <= VERNUM) && ((*(VersCheck+1)) <= REVNUM))
  1001.                                 {
  1002.                                     struct    VolEntry    *ThisEntry;
  1003.                                     UWORD    NumEntries, EntryType;
  1004.                                     BOOL    NoErr = TRUE;
  1005.  
  1006.                                         // Read in prefs
  1007.  
  1008.                                     if((Error = ReadChunkBytes(PrefsHandle, &NumEntries, sizeof(UWORD))) == sizeof(UWORD))
  1009.                                     {
  1010.                                         VolumeList.lh_Type = NumEntries;
  1011.  
  1012.                                         while(NumEntries-- && NoErr)
  1013.                                         {
  1014.                                             if((ThisEntry = AllocVec(sizeof(struct VolEntry), MEMF_CLEAR)))
  1015.                                             {
  1016.                                                 AddTail(&VolumeList, (struct Node *)ThisEntry);
  1017.                                                 ThisEntry->Link.ln_Name = ThisEntry->VolName;
  1018.  
  1019.                                                 if((Error = ReadChunkBytes(PrefsHandle, &EntryType, sizeof(UWORD))) == sizeof(UWORD))
  1020.                                                 {
  1021.                                                     ThisEntry->Link.ln_Type = EntryType;
  1022.  
  1023.                                                     if((Error = ReadChunkBytes(PrefsHandle, &ThisEntry->VolName, 130)) == 130)
  1024.                                                     {
  1025.                                                         if((Error = ReadChunkBytes(PrefsHandle, &ThisEntry->IconName, 256)) == 256)
  1026.                                                         {
  1027.                                                             if((Error = ReadChunkBytes(PrefsHandle, &ThisEntry->Left, (sizeof(UWORD) * 4))) != (sizeof(UWORD) * 4))
  1028.                                                                 NoErr = FALSE;
  1029.                                                         }
  1030.                                                     }
  1031.                                                 }
  1032.                                             }
  1033.                                             else
  1034.                                                 NoErr = FALSE;
  1035.                                         }
  1036.                                         GoOn = NoErr;
  1037.                                     }
  1038.  
  1039.                                     if(!NoErr)
  1040.                                         Error = IoErr();
  1041.                                 }
  1042.                             }
  1043.                         }
  1044.                     }
  1045.                 }
  1046.                 CloseIFF(PrefsHandle);
  1047.             }
  1048.  
  1049.             Close(PrefsHandle->iff_Stream);
  1050.         }
  1051.         else
  1052.             Error = IoErr();
  1053.  
  1054.         FreeIFF(PrefsHandle);
  1055.     }
  1056.     else
  1057.         Error = ERR_NOMEM;
  1058.  
  1059.     if(!GoOn && Error != ERROR_OBJECT_NOT_FOUND)
  1060.         DisplayError(Error, (ULONG)PrefsName);
  1061.  
  1062.  
  1063.     return(GoOn);
  1064. }
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072. /**********************************************************************/
  1073. /*                           Get a filename                           */
  1074. /**********************************************************************/
  1075. BOOL GetFileName(struct Window *Window, char *Title, char *FileName)
  1076. {
  1077.     struct    Rectangle    ScrRec;
  1078.     struct    FileRequester    *FileReq;
  1079.     char    Drawer[256],
  1080.         File[256];
  1081.     UWORD    Left, Top, Width, Height, i;
  1082.     BOOL    Result = FALSE;
  1083.  
  1084.     if(QueryOverscan(GetVPModeID(&Window->WScreen->ViewPort), &ScrRec, OSCAN_TEXT))
  1085.     {
  1086.         Width    = ((ScrRec.MaxX - ScrRec.MinX + 1) * 45) / 100;
  1087.         Height    = ((ScrRec.MaxY - ScrRec.MinY + 1) * 8) / 10;
  1088.         Left    = (((ScrRec.MaxX + 1) - Width) >> 1) - Window->WScreen->LeftEdge;
  1089.         Top    = (((ScrRec.MaxY + 1) - Height) >> 1) - Window->WScreen->TopEdge;
  1090.  
  1091.             // Get initial path
  1092.  
  1093.         if(PathPart(FileName) != (UBYTE *)&FileName[0])
  1094.         {
  1095.             for(i = 0; i < 256; i++)
  1096.                 Drawer[i] = '\0';
  1097.             strncpy(Drawer, FileName, (PathPart(FileName) - FileName));
  1098.         }
  1099.         else
  1100.             strcpy(Drawer, "");
  1101.  
  1102.             // Get FileName
  1103.  
  1104.         strcpy(File, FilePart(FileName));
  1105.  
  1106.         if((FileReq = AllocAslRequestTags(ASL_FileRequest,
  1107.             ASLFR_Screen,        Window->WScreen,
  1108.             ASLFR_Window,        Window,
  1109.             ASLFR_PrivateIDCMP,    TRUE,
  1110.             ASLFR_SleepWindow,     TRUE,
  1111.             ASLFR_TitleText,    Title,
  1112.             ASLFR_InitialDrawer,    (ULONG)Drawer,
  1113.             ASLFR_InitialFile,    (ULONG)File,
  1114.             ASLFR_InitialLeftEdge,    Left,
  1115.             ASLFR_InitialTopEdge,    Top,
  1116.             ASLFR_InitialWidth,    Width,
  1117.             ASLFR_InitialHeight,    Height,
  1118.             ASLFR_InitialPattern,    "#?.info",
  1119.         TAG_DONE)))
  1120.         {
  1121.             if(AslRequest(FileReq, NULL) && (strlen(FileReq->fr_File)))
  1122.             {
  1123.                     // Remove filetypes
  1124.  
  1125.                 strcpy(FileName, "");
  1126.  
  1127.                 AddPart(FileName, FileReq->fr_Drawer, 256);
  1128.                 AddPart(FileName, FileReq->fr_File, 256);
  1129.  
  1130.                 Result = TRUE;
  1131.             }
  1132.  
  1133.             FreeAslRequest(FileReq);
  1134.         }
  1135.     }
  1136.  
  1137.     return(Result);
  1138. }
  1139.  
  1140.  
  1141.  
  1142. /**********************************************************************/
  1143. /*        Check for existance of a volume within the user list        */
  1144. /**********************************************************************/
  1145. BOOL CheckExists(char *Name)
  1146. {
  1147.     BOOL    RetVal = FALSE;
  1148.  
  1149.     ObtainSemaphore(&MySemaphore);
  1150.  
  1151.     if(!IsListEmpty(&VolumeList))
  1152.     {
  1153.         struct    VolEntry    *ThisEntry    = (struct VolEntry *)VolumeList.lh_Head;
  1154.  
  1155.         do
  1156.         {
  1157.             if(!stricmp(ThisEntry->VolName, Name))
  1158.                 RetVal = TRUE;
  1159.  
  1160.             ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  1161.         } while(!RetVal && ThisEntry->Link.ln_Succ);
  1162.     }
  1163.  
  1164.     ReleaseSemaphore(&MySemaphore);
  1165.  
  1166.     return(RetVal);
  1167. }
  1168.  
  1169.  
  1170.  
  1171.  
  1172. /**********************************************************************/
  1173. /*             Sort the complete list of devices/volumes              */
  1174. /**********************************************************************/
  1175. void SortList(struct List *VolList, BOOL DisplayType)
  1176. {
  1177.     UWORD    First, Last;
  1178.  
  1179.     if(DisplayType)
  1180.     {
  1181.         First    = LDF_VOLUMES;
  1182.         Last    = LDF_DEVICES;
  1183.     }
  1184.     else
  1185.     {
  1186.         First    = LDF_DEVICES;
  1187.         Last    = LDF_VOLUMES;
  1188.     }
  1189.  
  1190.         // Sort partial lists within one list
  1191.  
  1192.     if(!IsListEmpty(VolList))
  1193.     {
  1194.         struct    VolEntry    *ThisEntry    = (struct VolEntry *)VolList->lh_Head;
  1195.         UWORD    NumEntries            = VolList->lh_Type;
  1196.         UWORD    Left = 0, Right = 0;
  1197.  
  1198.             // Find boundaries of first type of entries
  1199.  
  1200.         while(ThisEntry->Link.ln_Type == First && NumEntries)
  1201.         {
  1202.             Right++;
  1203.             NumEntries--;
  1204.             ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  1205.         }
  1206.  
  1207.             // Sort`em
  1208.  
  1209.         if(Left < Right)
  1210.         {
  1211.             SortPartialList(VolList, Left, Right);
  1212.             Left = Right;
  1213.         }
  1214.  
  1215.             // Look for second type of entries
  1216.  
  1217.         while(ThisEntry->Link.ln_Type == Last && NumEntries)
  1218.         {
  1219.             Right++;
  1220.             NumEntries--;
  1221.             ThisEntry = (struct VolEntry *)ThisEntry->Link.ln_Succ;
  1222.         }
  1223.  
  1224.             // Sort`em
  1225.  
  1226.         if(Left < Right)
  1227.             SortPartialList(VolList, Left, Right);
  1228.     }
  1229. }
  1230.  
  1231.  
  1232.  
  1233. /**********************************************************************/
  1234. /*            Sort partial list, either devices or volumes            */
  1235. /**********************************************************************/
  1236. void SortPartialList(struct List *VolList, UWORD Left, UWORD Right)
  1237. {
  1238.     UWORD    i, j;
  1239.  
  1240.         // This is a simply Insertion Sort
  1241.         // I don`t think that there will be too many entries,
  1242.         // so this algorithm will do it. (IMHO)
  1243.  
  1244.     for(i = Left + 1; i < Right; i++)
  1245.     {
  1246.         struct    VolEntry    Spare, *CheckEntry;
  1247.  
  1248.             j = i;
  1249.  
  1250.             Spare        = *((struct VolEntry *)GetListEntry(VolList, i));
  1251.             CheckEntry    = (struct VolEntry *)GetListEntry(VolList, j - 1);
  1252.  
  1253.             while(stricmp(CheckEntry->VolName, Spare.VolName) > 0 && j > Left)
  1254.             {
  1255.                 struct    VolEntry    *RightEntry = (struct VolEntry *)CheckEntry->Link.ln_Succ;
  1256.  
  1257.                 strcpy(RightEntry->VolName, CheckEntry->VolName);
  1258.                 strcpy(RightEntry->IconName, CheckEntry->IconName);
  1259.                 RightEntry->Left    = CheckEntry->Left;
  1260.                 RightEntry->Top        = CheckEntry->Top;
  1261.                 RightEntry->UseAlt    = CheckEntry->UseAlt;
  1262.  
  1263.                 j--;
  1264.                 CheckEntry = (struct VolEntry *)CheckEntry->Link.ln_Pred;
  1265.             }
  1266.  
  1267.             CheckEntry = (struct VolEntry *)GetListEntry(VolList, j);
  1268.             strcpy(CheckEntry->VolName, Spare.VolName);
  1269.             strcpy(CheckEntry->IconName, Spare.IconName);
  1270.             CheckEntry->Left    = Spare.Left;
  1271.             CheckEntry->Top        = Spare.Top;
  1272.             CheckEntry->UseAlt    = Spare.UseAlt;
  1273.     }
  1274. }
  1275.